using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class UIN_SettingAudio : UIBaseNode
    {
        #region Template Generate,don't modify
        protected class UIB_UIN_SettingAudio
        {
            #region ObjectBinding Generate 
            public IQIGame.Onigao.Framework.ExSlider sliderRole { protected set; get; }
            public IQIGame.Onigao.Framework.ExSlider sliderGame { protected set; get; }
            public IQIGame.Onigao.Framework.ExSlider sliderBgm { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textGame { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textBgm { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textRole { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton buttonRole { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton buttonGame { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton buttonBgm { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExSlider>("sliderRole", out var __tbv0);
                this.sliderRole = __tbv0;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExSlider>("sliderGame", out var __tbv1);
                this.sliderGame = __tbv1;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExSlider>("sliderBgm", out var __tbv2);
                this.sliderBgm = __tbv2;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textGame", out var __tbv3);
                this.textGame = __tbv3;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textBgm", out var __tbv4);
                this.textBgm = __tbv4;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textRole", out var __tbv5);
                this.textRole = __tbv5;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("buttonRole", out var __tbv6);
                this.buttonRole = __tbv6;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("buttonGame", out var __tbv7);
                this.buttonGame = __tbv7;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("buttonBgm", out var __tbv8);
                this.buttonBgm = __tbv8;
            }


            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify

        #region fields

        private SettingAudioData data;
        private AudioPlayback audioPlayback;

        #endregion fields

        #region properties

        protected UIB_UIN_SettingAudio ui { get; set; }
        protected UIMsgDispatcher uiMsgDispatcher => this._msgDispatcher as UIMsgDispatcher;

        #endregion properties

        protected override void BeforeInit()
        {
            ui = new UIB_UIN_SettingAudio();
            ui.InitBinding(this.csObjBind);
        }

        protected override void OnInit()
        {

        }

        protected override void OnShow()
        {

        }

        protected override void OnHide()
        {
            StopTestAudio();
        }

        /// <summary>
        /// 添加UGUI侦听
        /// </summary>
        protected override void AddUGUIListener()
        {
            this.ui.sliderBgm.onValueChanged.AddListener(OnBgmChange);
            this.ui.sliderGame.onValueChanged.AddListener(OnGameChange);
            this.ui.sliderRole.onValueChanged.AddListener(OnRoleChange);

            this.ui.buttonBgm.onClick.AddListener(OnPlayBgm);
            this.ui.buttonGame.onClick.AddListener(OnPlaySfx);
            this.ui.buttonRole.onClick.AddListener(OnPlayVoice);
        }

        /// <summary>
        /// 添加全局侦听（MsgDispatcher）
        /// </summary>
        protected override void AddMsgListeners()
        {
        }

        protected override void OnDispose()
        {
            StopTestAudio();
        }

        #region methonds
        public void Show(int index)
        {
            this.data = GameDataCenter.PlayerData.setting.audioData;
            this.Show();
            this.ShowBgm();
            this.ShowGameSound();
            this.ShowRoleSound();
        }

        private void ShowBgm()
        {
            this.ui.textBgm.text = "" + ShowSlider(this.ui.sliderBgm, this.data.bgm);
        }

        private int ShowSlider(IQIGame.Onigao.Framework.ExSlider slider, int value)
        {
            int current = Math.Clamp(value, 0, 100);
            slider.minValue = 0;
            slider.maxValue = 100;
            slider.value = current;
            return current;
        }

        private void ShowGameSound()
        {
            this.ui.textGame.text = "" + ShowSlider(this.ui.sliderGame, this.data.sfx);
        }

        private void ShowRoleSound()
        {
            this.ui.textRole.text = "" + ShowSlider(this.ui.sliderRole, this.data.voice);
        }

        public void Save()
        {
            int bgm = GetSliderValue(this.ui.sliderBgm);
            int game = GetSliderValue(this.ui.sliderGame);
            int role = GetSliderValue(this.ui.sliderRole);
            int audioSource = 0;
            this.data.Set(Tuple.Create(bgm, game, role, audioSource));
            GameDataCenter.PlayerData.setting.SaveAudioData(this.data);
        }

        private int GetSliderValue(IQIGame.Onigao.Framework.ExSlider slider)
        {
            int current = (int)slider.value;
            return Math.Clamp(current, 0, 100);
        }

        private void OnBgmChange(float value)
        {
            int current = (int)value;
            if (this.data.bgm != current)
            {
                this.data.bgm = current;
                SetVolume(AudioVolumeType.Bgm, current);
                this.RefreshBgmText();
            }
        }

        private void SetVolume(AudioVolumeType type, int value)
        {
            ManagerCenter.Audio.SetVolume(type, Mathf.Clamp01(value / 100.0f));
        }

        private void RefreshBgmText()
        {
            this.ui.textBgm.text = "" + GetSliderValue(this.ui.sliderBgm);
        }

        private void OnGameChange(float value)
        {
            int current = (int)value;
            if (this.data.sfx != current)
            {
                this.data.sfx = current;
                SetVolume(AudioVolumeType.Sfx, current);
                this.RefreshGameText();
            }
        }

        private void RefreshGameText()
        {
            this.ui.textGame.text = "" + GetSliderValue(this.ui.sliderGame);
        }

        private void OnRoleChange(float value)
        {
            int current = (int)value;
            if (this.data.voice != current)
            {
                this.data.voice = current;
                SetVolume(AudioVolumeType.Voice, current);
                this.RefreshRoleText();
            }
        }

        private void RefreshRoleText()
        {
            this.ui.textRole.text = "" + GetSliderValue(this.ui.sliderRole);
        }
        private void OnPlayBgm()
        {
            StopTestAudio();
            _OnPlayBgm().Forget();
        }

        private async UniTaskVoid _OnPlayBgm()
        {
            ManagerCenter.Audio.SetMute(AudioVolumeType.Bgm, true);
            await UniTask.Delay(100);
            ManagerCenter.Audio.SetMute(AudioVolumeType.Bgm, false);
        }

        private void OnPlaySfx()
        {
            PlayTestAudioAndStopLastAudio(APIUISettings.AudioCids_Sfx);
        }

        private void PlayTestAudioAndStopLastAudio(int[] audioCids)
        {
            StopTestAudio();
            PlayRandomTestAudio(audioCids);
        }

        private void StopTestAudio()
        {
            if (audioPlayback != null)
                ManagerCenter.Audio.StopAudioByBack(audioPlayback);
            audioPlayback = null;
        }

        private void PlayRandomTestAudio(int[] audioCids)
        {
            int cnt = audioCids?.Length ?? 0;
            if (cnt == 0)
                return;
            int index = cnt > 1 ? UnityEngine.Random.Range(0, cnt) : 0;
            audioPlayback = ManagerCenter.Audio.PlayAudioById(audioCids[index]);
        }

        private void OnPlayVoice()
        {
            PlayTestAudioAndStopLastAudio(APIUISettings.AudioCids_Voice);
        }
        #endregion methonds
    }
}
